import bcrypt from 'bcryptjs';
import crypto from 'crypto';
import jwt from 'jsonwebtoken';

// 安全工具类
export class SecurityUtils {
  private static readonly SALT_ROUNDS = 12;
  private static readonly ENCRYPTION_ALGORITHM = 'aes-256-gcm';
  private static readonly JWT_SECRET = process.env.JWT_SECRET || 'default-secret-key-for-development-only';
  private static readonly ENCRYPTION_KEY = process.env.ENCRYPTION_KEY || crypto.randomBytes(32);

  // 密码哈希
  static async hashPassword(password: string): Promise<string> {
    return bcrypt.hash(password, this.SALT_ROUNDS);
  }

  // 验证密码
  static async verifyPassword(password: string, hashedPassword: string): Promise<boolean> {
    return bcrypt.compare(password, hashedPassword);
  }

  // 生成随机字符串
  static generateRandomString(length: number = 32): string {
    return crypto.randomBytes(length).toString('hex');
  }

  // 生成UUID
  static generateUUID(): string {
    return crypto.randomUUID();
  }

  // 加密敏感数据
  static encrypt(text: string): { encrypted: string; iv: string; tag: string } {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipher(this.ENCRYPTION_ALGORITHM, this.ENCRYPTION_KEY);
    cipher.setAAD(Buffer.from('additional-data'));
    
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    
    const tag = cipher.getAuthTag();
    
    return {
      encrypted,
      iv: iv.toString('hex'),
      tag: tag.toString('hex')
    };
  }

  // 解密敏感数据
  static decrypt(encryptedData: { encrypted: string; iv: string; tag: string }): string {
    const decipher = crypto.createDecipher(this.ENCRYPTION_ALGORITHM, this.ENCRYPTION_KEY);
    decipher.setAAD(Buffer.from('additional-data'));
    decipher.setAuthTag(Buffer.from(encryptedData.tag, 'hex'));
    
    let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    
    return decrypted;
  }

  // 生成JWT令牌
  static generateJWT(payload: any, expiresIn: string = '24h'): string {
    return jwt.sign(payload, this.JWT_SECRET, { expiresIn });
  }

  // 验证JWT令牌
  static verifyJWT(token: string): any {
    try {
      return jwt.verify(token, this.JWT_SECRET);
    } catch (error) {
      throw new Error('Invalid token');
    }
  }

  // 生成API密钥
  static generateAPIKey(): string {
    const timestamp = Date.now().toString();
    const randomBytes = crypto.randomBytes(16).toString('hex');
    return `dw_${timestamp}_${randomBytes}`;
  }

  // 哈希API密钥
  static hashAPIKey(apiKey: string): string {
    return crypto.createHash('sha256').update(apiKey).digest('hex');
  }

  // 验证API密钥
  static verifyAPIKey(apiKey: string, hashedKey: string): boolean {
    const hashedInput = this.hashAPIKey(apiKey);
    return crypto.timingSafeEqual(Buffer.from(hashedInput), Buffer.from(hashedKey));
  }

  // 生成CSRF令牌
  static generateCSRFToken(): string {
    return crypto.randomBytes(32).toString('base64');
  }

  // 验证CSRF令牌
  static verifyCSRFToken(token: string, sessionToken: string): boolean {
    return crypto.timingSafeEqual(Buffer.from(token), Buffer.from(sessionToken));
  }

  // 安全地比较字符串（防止时序攻击）
  static safeCompare(a: string, b: string): boolean {
    if (a.length !== b.length) {
      return false;
    }
    return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
  }

  // 生成安全的会话ID
  static generateSessionId(): string {
    return crypto.randomBytes(32).toString('base64url');
  }

  // 清理敏感信息
  static sanitizeForLog(obj: any): any {
    const sensitiveFields = ['password', 'token', 'secret', 'key', 'auth'];
    const sanitized = { ...obj };

    const sanitizeRecursive = (item: any): any => {
      if (typeof item !== 'object' || item === null) {
        return item;
      }

      if (Array.isArray(item)) {
        return item.map(sanitizeRecursive);
      }

      const result: any = {};
      for (const [key, value] of Object.entries(item)) {
        const lowerKey = key.toLowerCase();
        const isSensitive = sensitiveFields.some(field => lowerKey.includes(field));
        
        if (isSensitive) {
          result[key] = '[REDACTED]';
        } else {
          result[key] = sanitizeRecursive(value);
        }
      }
      return result;
    };

    return sanitizeRecursive(sanitized);
  }

  // 生成数据库连接密码的加密存储
  static encryptConnectionPassword(password: string): string {
    const encrypted = this.encrypt(password);
    return JSON.stringify(encrypted);
  }

  // 解密数据库连接密码
  static decryptConnectionPassword(encryptedPassword: string): string {
    try {
      const encryptedData = JSON.parse(encryptedPassword);
      return this.decrypt(encryptedData);
    } catch (error) {
      throw new Error('Failed to decrypt connection password');
    }
  }

  // 验证IP地址格式
  static isValidIP(ip: string): boolean {
    const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
    const ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
    return ipv4Regex.test(ip) || ipv6Regex.test(ip);
  }

  // 生成请求ID
  static generateRequestId(): string {
    const timestamp = Date.now().toString(36);
    const randomPart = crypto.randomBytes(8).toString('hex');
    return `req_${timestamp}_${randomPart}`;
  }

  // 计算文件哈希
  static calculateFileHash(buffer: Buffer): string {
    return crypto.createHash('sha256').update(buffer).digest('hex');
  }

  // 验证文件完整性
  static verifyFileIntegrity(buffer: Buffer, expectedHash: string): boolean {
    const actualHash = this.calculateFileHash(buffer);
    return this.safeCompare(actualHash, expectedHash);
  }

  // 生成安全的临时令牌
  static generateTempToken(expiresInMinutes: number = 30): {
    token: string;
    expiresAt: Date;
  } {
    const token = crypto.randomBytes(32).toString('base64url');
    const expiresAt = new Date(Date.now() + expiresInMinutes * 60 * 1000);
    
    return { token, expiresAt };
  }

  // 验证临时令牌是否过期
  static isTokenExpired(expiresAt: Date): boolean {
    return new Date() > expiresAt;
  }

  // 生成数字签名
  static generateSignature(data: string, secret: string): string {
    return crypto.createHmac('sha256', secret).update(data).digest('hex');
  }

  // 验证数字签名
  static verifySignature(data: string, signature: string, secret: string): boolean {
    const expectedSignature = this.generateSignature(data, secret);
    return this.safeCompare(signature, expectedSignature);
  }

  // 限制字符串长度并添加省略号
  static truncateString(str: string, maxLength: number): string {
    if (str.length <= maxLength) {
      return str;
    }
    return str.substring(0, maxLength - 3) + '...';
  }

  // 转义HTML特殊字符
  static escapeHtml(unsafe: string): string {
    return unsafe
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#039;');
  }

  // 生成安全的文件名
  static generateSecureFileName(originalName: string): string {
    const ext = originalName.split('.').pop() || '';
    const timestamp = Date.now();
    const randomString = crypto.randomBytes(8).toString('hex');
    return `${timestamp}_${randomString}.${ext}`;
  }
}